﻿using IPlugin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SessionManager
{
    public class SessionManager : IPlugin.IPlugin
    {
        #region InfoPlugin

        public string[] Authors
        {
            get
            {
                return new string[] { "Manuel Fernandez" };
            }
        }

        public string Name
        {
            get
            {
                return "SessionManager";
            }
        }

        public string Description
        {
            get
            {
                return "Manages sessions";
            }
        }

        public IPlugin.PluginRing Ring
        {
            get
            {
                return IPlugin.PluginRing.Ring0;
            }
        }
        #endregion
        
        public Model.Elements.HttpPacket Start(Model.Elements.HttpPacket packet)
        {
            if (packet is Model.Elements.HttpResponsePacket)
            {
                Model.Elements.HttpResponsePacket response = packet as Model.Elements.HttpResponsePacket;
                Model.Elements.HttpRequestPacket request = response.GetRequestPacket();
                
                bool hasSession = false;
                bool sessionAsigned = false;

                if (request != null)
                {
                    foreach (Model.Elements.HttpHeader header in request.lstHeaders)
                    {
                        if (header.name.ToLower() == "cookie")
                        {
                            string[] cookies = header.value.Split(';');

                            foreach (string cookie in cookies)
                            {
                                if (string.IsNullOrEmpty(cookie))
                                    continue;

                                Model.Elements.SingleCookieHeader[] singleCookieList = Model.Elements.SingleCookieHeader.Parse(cookie);

                                foreach (Model.Elements.SingleCookieHeader singleCookie in singleCookieList)
                                {
                                    if (singleCookie.name == Configuration.Configuration.cookieSessionName)
                                    {
                                        if (IPlugin.Sessions.ExistsSession(singleCookie.value))
                                            hasSession = true;
                                        else
                                        {
                                            // Session doesn't exist. Let's generate a new one
                                            Session session = IPlugin.Sessions.GenerateSession();
                                            response.AddHeader(new Model.Elements.HttpHeader("Set-Cookie", string.Format("{0}={1};", Configuration.Configuration.cookieSessionName, session.hash)));
                                            Sessions.AddSession(session);
                                            AddDefaultElements(session, request);
                                            sessionAsigned = true;
                                        }
                                    }
                                }
                                /*
                                if (singleCookie == null)
                                    continue;

                                if (singleCookie.name == Configuration.Configuration.cookieSessionName)
                                {
                                    if (IPlugin.Sessions.ExistsSession(singleCookie.value))
                                        hasSession = true;
                                    else
                                    {
                                        // Session doesn't exist. Let's generate a new one
                                        Session session = IPlugin.Sessions.GenerateSession();
                                        response.AddHeader(new Model.Elements.HttpHeader("Set-Cookie", string.Format("{0}={1};", Configuration.Configuration.cookieSessionName, session.hash)));
                                        Sessions.AddSession(session);
                                        AddDefaultElements(session, request);
                                        sessionAsigned = true;
                                    }
                                }*/
                            }
                        }
                    }
                }

                if (!hasSession && !sessionAsigned)
                {
                    // doesn't have a session cookie, let's send one! :)
                    Session session = IPlugin.Sessions.GenerateSession();
                    response.AddHeader(new Model.Elements.HttpHeader("Set-Cookie", string.Format("{0}={1};", Configuration.Configuration.cookieSessionName, session.hash)));
                    AddDefaultElements(session, request);
                    Sessions.AddSession(session);
                }

                return response;
            }

            return packet;
        }

        private void AddDefaultElements(Session session, Model.Elements.HttpRequestPacket request)
        {
            session.elements.Add("ip", request.clientIp);
        }
    }

}
